package limiter

import (
	"context"
	"sync"
	"time"
)

// LocalLimiter 基于本地内存的限流器
type LocalLimiter struct {
	mu       sync.Mutex
	counters map[string]*counter
}
type counter struct {
	entries []int64 // 存储时间戳的环形缓冲区
	index   int     // 当前写入位置
}

func NewLocalLimiter() *LocalLimiter {
	return &LocalLimiter{
		counters: make(map[string]*counter),
	}
}
func (l *LocalLimiter) Allow(ctx context.Context, key string, limit int, window time.Duration) (bool, error) {
	l.mu.Lock()
	defer l.mu.Unlock()

	now := time.Now().UnixNano()
	windowNano := window.Nanoseconds()

	// 获取或初始化计数器
	c, ok := l.counters[key]
	if !ok {
		c = &counter{
			entries: make([]int64, limit),
			index:   0,
		}
		l.counters[key] = c
	}

	// 清理过期记录
	validEntries := 0
	for i := 0; i < limit; i++ {
		if now-c.entries[i] <= windowNano {
			validEntries++
		}
	}

	if validEntries >= limit {
		return false, nil
	}

	// 记录当前请求时间
	c.entries[c.index] = now
	c.index = (c.index + 1) % limit
	return true, nil
}
